package com.yitiao.simple.websocket;

import com.yitiao.simple.http.HttpServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.SneakyThrows;

public class WebSocketServer {
    @SneakyThrows
    public static void main(String[] args) {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap server = new ServerBootstrap();
        server.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 添加handler 注意顺序，一般编解码在最前面，自定义在最后
                        ch.pipeline().addLast(new HttpServerCodec()) // http编解码
                                .addLast(new ChunkedWriteHandler()) // 添加对块方式写的支持
                                .addLast(new HttpObjectAggregator(8192))  // 将多段数据整合
                                /*  1. 对应websocket ，它的数据是以 帧(frame) 形式传递
                                    2. 可以看到WebSocketFrame 下面有六个子类
                                    3. 浏览器请求时 ws://localhost:8802/index 表示请求的uri
                                    4. WebSocketServerProtocolHandler 核心功能是将 http协议升级为 ws协议 , 保持长连接
                                    5. 是通过一个 状态码 101
                                 */
                                .addLast(new WebSocketServerProtocolHandler("/index")) //
                                .addLast(new WebSocketServerHandler())
                        .addLast(new HttpServerHandler());
                    }
                });
        ChannelFuture future = server.bind(8802).sync();
        System.out.println("server is started...");

        future.channel().closeFuture().sync();

        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}
